package com.xuecheng.content.service.jobhandler;

import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.content.feignclient.CourseIndex;
import com.xuecheng.content.feignclient.SearchServiceClient;
import com.xuecheng.content.mapper.CoursePublishMapper;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.content.service.CoursePublishService;
import com.xuecheng.messagesdk.model.po.MqMessage;
import com.xuecheng.messagesdk.service.MessageProcessAbstract;
import com.xuecheng.messagesdk.service.MqMessageService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;

@Component
@Slf4j
public class CoursePublishTask extends MessageProcessAbstract {

    @Resource
    CoursePublishService coursePublishService;
    @Resource
    SearchServiceClient searchServiceClient;
    @Resource
    CoursePublishMapper coursePublishMapper;

    //任务调度入口 别忘了引入XxlJobConfig配置类
    @XxlJob("CoursePublishJobHandler")
    public void coursePublishJobHandler() throws Exception {
        // 分片参数
        int shardIndex = XxlJobHelper.getShardIndex();
        int shardTotal = XxlJobHelper.getShardTotal();
        log.debug("shardIndex="+shardIndex+",shardTotal="+shardTotal);
        //参数:分片序号、分片总数、消息类型、一次最多取到的任务数量、一次任务调度执行的超时时间
        process(shardIndex,shardTotal,"course_publish",30,60);
    }

    @Override//之所以要把状态一个个判断,是为了确保任务中断后重新开始保证任务的幂等性,不管执行多少次结果都一样,还能省去执行执行重复任务
    public boolean execute(MqMessage mqMessage) {
//        从mqMessage拿到课程ID
        long courseId = Long.parseLong(mqMessage.getBusinessKey1());
//        课程静态化上传到minio
        generateCourseHtml(mqMessage,courseId);
//        向elasticsearch写索引数据 todo elasticsearch
        saveCourseIndex(mqMessage,courseId);
//         向redis写入缓存
//        返回true表示任务完成
        return true;
    }
//    生成静态化页面并上传至文件系统
    private void generateCourseHtml(MqMessage mqMessage,Long courseId){
        Long taskId = mqMessage.getId();
        MqMessageService mqMessageService = this.getMqMessageService();//来自父类
//         做任务幂等性处理
//        查询出该阶段的执行状态
        int stageOne = mqMessageService.getStageOne(taskId);//这里也可以直接从mqMessage中取出
        if (stageOne > 0){//0为未完成,1为完成
            log.debug("课程静态化任务完成,无需处理");
             return;
        }
//      执行课程静态化
        File file = coursePublishService.generateCourseHtml(courseId);
        if (file == null){//这里一定要往外跑,中断执行
            XueChengPlusException.cast("生成的静态页面为空");
        }
//        将html上传到minio
        coursePublishService.uploadCourseHtml(courseId,file);
//        更改状态
        mqMessageService.completedStageOne(taskId);
    }

// 第二阶段
    private void saveCourseIndex(MqMessage mqMessage,Long courseId){
        Long stageState2 = Long.parseLong(mqMessage.getStageState2());
        if (stageState2 > 0){
            log.debug("课程索引已写入,无需处理");
            return;
        }
//        查询课程发布表获取信息
        CoursePublish coursePublish = coursePublishMapper.selectById(courseId);
//        添加索引
        CourseIndex courseIndex = new CourseIndex();
        BeanUtils.copyProperties(coursePublish,courseIndex);
        Boolean add = searchServiceClient.add(courseIndex);
        if (!add){
            XueChengPlusException.cast("远程调用搜索服务添加索引失败");
        }
//        完成状态更改
        this.getMqMessageService().completedStageTwo(mqMessage.getId());

    }
}
